#include "mythreadforsql.h"
#include <QSqlQuery>
#include <QDebug>
#include <QDateTime>
#include <QBuffer>
#include <QSharedMemory>
#include "mythreadforserial.h"
MyThreadForSql::MyThreadForSql(QSqlDatabase &db, int col) :
    m_db(db),
    m_col(col)
{

}

void MyThreadForSql::run()
{
    SharedMemory_write("world");
    msleep(1000);
    //SharedMemory_write("555555");
}

void MyThreadForSql::SharedMemory_write(QString data)
{
    //创建共享内存对象
    //m_SharedMemory = new QSharedMemory("SharedMermoryForSerial");
    m_SharedMemory_write = new QSharedMemory();
    //声明共享内存的密秘钥
    m_SharedMemory_write->setKey("SharedMermoryForSerial");
    //将共享内存与当前线程绑定
    if(m_SharedMemory_write->isAttached())           //判断是否已经关联内存，如果是已经关联了，就要通过detach断开
    {
        //将线程与共享内存块分离
        if(!m_SharedMemory_write->detach())
        {
             qDebug() << "Unable to detach from shared memory.";
        }
    }
    //QString data = "hello world!";

    if(data.length())       //判断是否有内容
    {
        QBuffer buffer;                     //将字符串转为字节的介质
        buffer.open(QBuffer::ReadWrite);
        QDataStream out(&buffer);           //数据流
        out << data;
        int size = buffer.size();           //获得字节大小
        //创建共享内存
        if(!m_SharedMemory_write->create(size))
        {
            qDebug() << m_SharedMemory_write->errorString() << "\n Unable to create shared memory segment.";
            //return ;
            m_SharedMemory_write->attach();     //如果无法创建以当前key为标识的共享内存，则说明内存已被创建(或者说还在使用，还没有被销毁)，则我们通过attach()进行联系
        }
        //向共享内存写数据
        m_SharedMemory_write->lock();         //锁定共享内存
        char *to = (char*)m_SharedMemory_write->data(); //将指向刚创建内存的地址传给指针变量to
        const char *from = buffer.data().data(); //被共享内存的数据
        memcpy(to , from, qMin(m_SharedMemory_write->size(), size));
        m_SharedMemory_write->unlock();
    }
    qDebug()<<"打印输出data"<<data;
}

bool MyThreadForSql::update_to_sql(double index, double data)
{
    QSqlQuery query;
    query.exec("SELECT * FROM testformanagement;");
    int i = query.size();
    i++;
    qDebug()<<"update_to_sql  "<<i;
    //INSERT INTO testformanagement (id, date, whatever) VALUES(2, NOW(), 13);
    query.exec(QString("INSERT INTO testformanagement (id, date, whatever) VALUES(%1, NOW(), %2);").arg(i).arg(data));
    qDebug()<<"插入数据成功！";
    return true;
}

void MyThreadForSql::query_by_datatime(QStringList data)
{
    qDebug()<<"到这剧了吗";
    QString day1, mouth1, year1, all1;
    QString day2, mouth2, year2, all2;
    year1 = data[0];
    mouth1 = data[1];
    day1 = data[2];
    year2 = data[3];
    mouth2 = data[4];
    day2 = data[5];
    QSqlQuery query;
//    qDebug()<<(QString("select `data`, t_furnace, t_wind1, t_wind2,t_wind3, t_tower1, t_tower2, t_tower3, v_coal,v_grain, rh_after_grain, rh_before_grain from managesystem1_copy_copy where `data` BETWEEN '%1-%2-%3' and '%4-%5-%6'").arg(year1).arg(mouth1).arg(day1).arg(year2).arg(mouth2).arg(day2));
    query.exec(QString("select `data`, t_furnace, t_wind1, t_wind2,t_wind3, t_tower1, t_tower2, t_tower3, v_coal,v_grain, rh_after_grain, rh_before_grain from managesystem1_copy_copy where `data` BETWEEN '%1-%2-%3' and '%4-%5-%6'").arg(year1).arg(mouth1).arg(day1).arg(year2).arg(mouth2).arg(day2));
    this->search_by_query(query);
    qDebug()<<"子线程查询成功后，发送信号更新SubWidget2的容器内容";
    emit(refresh_vector());
}

void MyThreadForSql::search_by_query(QSqlQuery &query)
{
    //向容器中更新数据前，想将其清空
    this->clear_vector();

    int temp_row = query.size();               //得到表格的行数
    if(temp_row<1)
    {
        qDebug()<<"search_by_query报错:说明查询语句错了，或者说这个query查询出来就是没内容？";
        return ;
    }
    else if (temp_row>500)          //当查询出数据的个数大于500时，我们将数据集置为500
    {
        temp_row = 500;
    }
    int temp=0;                 //记录当前数据是第几行
    while (query.next())        //void search_by_query(const QSqlQuery& query); //这里不能将query以常成员的形式传入，因为常成员函数不能调用普通的成员函数，即query无法调用.next()函数
    {
        for(int j=0; j < this->m_col; j++)
        {
            if(j == 0)   //第一列数据是日期这样的，所以我们就不传入int了
            {
                //帮助向容器中插入数据
                //this->push_to_vector<QString>(j, query.value(j).toString());
                             //这样做不合适，但当下先这样试着
                m_v_date.push_back(static_cast<double>(query.value(j).toDateTime().toTime_t()));
            }
            else
            {
                this->push_to_vector(j, query.value(j).toDouble());
            }
        }
        temp++;
    }
}

void MyThreadForSql::push_to_vector(int d, double data)
{
    switch (d)
    {
//        case e_data:
//            if(std::is_same<T1, QString>::value)
//            {
//                m_v_date.push_back(data);
//                break;
//            }

        case e_t_furnace:
            m_v_t_furnace.push_back(data);
            break;
        case e_t_wind1:
            m_v_t_wind1.push_back(data);
            break;
        case e_t_wind2:
            m_v_t_wind2.push_back(data);
            break;
        case e_t_wind3:
            m_v_t_wind3.push_back(data);
            break;
        case e_t_tower1:
            m_v_t_tower1.push_back(data);
            break;
        case e_t_tower2:
            m_v_t_tower2.push_back(data);
            break;
        case e_t_tower3:
            m_v_t_tower3.push_back(data);
            break;
        case e_v_coal:
            m_v_v_coal.push_back(data);
            break;
        case e_v_grain:
            m_v_v_grain.push_back(data);
            break;
        case e_rh_after_grain:
            m_v_rh_after_grain.push_back(data);
            break;
        case e_rh_before_grain:
            m_v_rh_before_grain.push_back(data);
            break;
        default:
            qDebug()<<"d="<< d <<"向容器插入数据失败\n";
        break;
    }
}

/**
 * @brief SubWidget2::getSequence 根据索引得到目标容器
 * @param i 容器索引
 * @return
 */
//template <class T>
//T MyThreadForSql::getSequence(int i)
//{
//    switch (i)
//    {
//        case e_data:
//            return static_cast<T>(m_v_date);
//        case e_t_furnace:
//            return static_cast<T>(m_v_t_furnace);
//            break;
//        case e_t_wind1:
//            return static_cast<T>(m_v_t_wind1);
//            break;
//        case e_t_wind2:
//            return static_cast<T>(m_v_t_wind2);
//            break;
//        case e_t_wind3:
//            return static_cast<T>(m_v_t_wind3);
//            break;
//        case e_t_tower1:
//            return static_cast<T>(m_v_t_tower1);
//            break;
//        case e_t_tower2:
//            return static_cast<T>(m_v_t_tower2);
//            break;
//        case e_t_tower3:
//            return static_cast<T>(m_v_t_tower3);
//            break;
//        case e_v_coal:
//            return static_cast<T>(m_v_v_coal);
//            break;
//        case e_v_grain:
//            return static_cast<T>(m_v_v_grain);
//            break;
//        case e_rh_after_grain:
//            return static_cast<T>(m_v_rh_after_grain);
//            break;
//        case e_rh_before_grain:
//            return static_cast<T>(m_v_rh_before_grain);
//            break;
//        default:
//            qDebug()<<"获取容器失败了";
//        break;
//    }
//    qDebug()<<"getSequence(int i) ：未找到您想要获取的容器，请重新输入"<<endl;
//}
/**
 * @brief SubWidget2::getSequence 根据索引得到目标容器
 * @param i 容器索引
 * @return
 */
QVector<double> MyThreadForSql::getSequence(int i)
{
    switch (i)
    {
        case e_data:
            return m_v_date;
        case e_t_furnace:
            return m_v_t_furnace;
            break;
        case e_t_wind1:
            return m_v_t_wind1;
            break;
        case e_t_wind2:
            return m_v_t_wind2;
            break;
        case e_t_wind3:
            return m_v_t_wind3;
            break;
        case e_t_tower1:
            return m_v_t_tower1;
            break;
        case e_t_tower2:
            return m_v_t_tower2;
            break;
        case e_t_tower3:
            return m_v_t_tower3;
            break;
        case e_v_coal:
            return m_v_v_coal;
            break;
        case e_v_grain:
            return m_v_v_grain;
            break;
        case e_rh_after_grain:
            return m_v_rh_after_grain;
            break;
        case e_rh_before_grain:
            return m_v_rh_before_grain;
            break;
        default:
            qDebug()<<"获取容器失败了";
        break;
    }
    qDebug()<<"getSequence(int i) ：未找到您想要获取的容器，请重新输入"<<endl<<i;
}

void MyThreadForSql::clear_vector()
{
    qDebug()<<m_v_t_wind1.size();
    m_v_date.clear();
    m_v_t_furnace.clear();
    m_v_t_wind1.clear();
    m_v_t_wind2.clear();
    m_v_t_wind3.clear();
    m_v_t_tower1.clear();
    m_v_t_tower2.clear();
    m_v_t_tower3.clear();
    m_v_v_coal.clear();
    m_v_v_grain.clear();
    m_v_rh_after_grain.clear();
    m_v_rh_before_grain.clear();
    qDebug()<<m_v_t_wind1.size();
    //将大小都重置为0
    m_v_date.resize(0);
    m_v_t_furnace.resize(0);
    m_v_t_wind1.resize(0);
    m_v_t_wind2.resize(0);
    m_v_t_wind3.resize(0);
    m_v_t_tower1.resize(0);
    m_v_t_tower2.resize(0);
    m_v_t_tower3.resize(0);
    m_v_v_coal.resize(0);
    m_v_v_grain.resize(0);
    m_v_rh_after_grain.resize(0);
    m_v_rh_before_grain.resize(0);
    qDebug()<<m_v_t_wind1.size();
}
